﻿using fastNpoi.Model;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace fastNpoi.Interface
{
    public interface IFastNpoi<T> where T : class,new()
    {
        /// <summary>
        /// 根据文件路径加载一个workbook
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        IFastNpoi<T> InitWorkbook(string path);
        /// <summary>
        /// 根据文件流加载一个workbook
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        IFastNpoi<T> InitWorkbook(Stream stream);
        /// <summary>
        /// 创建一个workbook
        /// </summary>
        /// <returns></returns>
        IFastNpoi<T> CreateWorkbook();
        /// <summary>
        /// 创建一个sheet页
        /// </summary>
        /// <param name="name">sheet页名称</param>
        /// <returns></returns>
        IFastNpoi<T> CreateSheet(string name);
        /// <summary>
        /// 创建一个sheet
        /// </summary>
        /// <returns></returns>
        IFastNpoi<T> CreateSheet();
        /// <summary>
        /// 产生一个完全一样的实现类对象
        /// </summary>
        /// <returns></returns>
        IFastNpoi<T> Clone();
        /// <summary>
        /// 根据索引读取sheet页
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        IFastNpoi<T> GetSheet(int index = 0);
        /// <summary>
        /// 根据sheet页名称读取sheet页
        /// </summary>
        /// <param name="name">sheet名</param>
        /// <returns></returns>
        IFastNpoi<T> GetSheet(string name);
        /// <summary>
        /// 数据赋值实现类替换
        /// </summary>
        /// <param name="operation">赋值取值实现类</param>
        /// <returns></returns>
        IFastNpoi<T> SetDataOperation(IDataOperation operation);
        /// <summary>
        /// 设置表头索引位置 默认为0
        /// </summary>
        /// <param name="headerIndex"></param>
        /// <returns></returns>
        IFastNpoi<T> SetHeaderIndex(int headerIndex);
        /// <summary>
        /// 设置列起始位置 默认为0
        /// </summary>
        /// <param name="columnStartIndex"></param>
        /// <returns></returns>
        IFastNpoi<T> SetColumnStartIndex(int columnStartIndex);
        /// <summary>
        /// 每行间隔列数
        /// </summary>
        /// <param name="offset"></param>
        /// <returns></returns>
        IFastNpoi<T> SetRowSkipNumber(int offset);
        /// <summary>
        /// 每列间隔列数
        /// </summary>
        /// <param name="offset"></param>
        /// <returns></returns>
        IFastNpoi<T> SetColumnSkipNumber(int offset);
        /// <summary>
        /// 设置表头和数据之间的间隔行数 默认为1
        /// </summary>
        /// <param name="offset"></param>
        /// <returns></returns>
        IFastNpoi<T> SetHeaderSkipNumber(int offset);
        /// <summary>
        /// 设置表头的样式
        /// </summary>
        /// <param name="styleFunc"></param>
        /// <returns></returns>
        IFastNpoi<T> SetHeaderStyle(Func<IWorkbook,ICellStyle> styleFunc);
        /// <summary>
        /// 设置数据的样式
        /// </summary>
        /// <param name="styleFunc"></param>
        /// <returns></returns>
        IFastNpoi<T> SetDataStyle(Func<IWorkbook,ICellStyle> styleFunc);
        /// <summary>
        /// 设置添加批注的单元格样式
        /// </summary>
        /// <param name="styleFunc"></param>
        /// <returns></returns>
        IFastNpoi<T> SetCommentCellStyle(Func<IWorkbook, ICellStyle> styleFunc);
        /// <summary>
        /// 设置json字段映射规则
        /// </summary>
        /// <param name="columnExpression">json字段表达式</param>
        /// <param name="map">映射规则(key为映射的表头名,value为Json字段的key)</param>
        /// <returns></returns>
        IFastNpoi<T> SetJsonMapping(Expression<Func<T, object>> columnExpression, Dictionary<string, string> map);
        /// <summary>
        /// 设置json字段映射规则
        /// </summary>
        /// <param name="columnName">json字段名称</param>
        /// <param name="map">映射规则(key为映射的表头名,value为Json字段的key)</param>
        /// <returns></returns>
        IFastNpoi<T> SetJsonMapping(string columnName, Dictionary<string, string> map);
        /// <summary>
        /// 设置批注的默认可见性
        /// </summary>
        /// <param name="visable"></param>
        /// <returns></returns>
        IFastNpoi<T> SetCommentVisable(bool visable);
        /// <summary>
        /// 设置实体list
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        IFastNpoi<T> SetDataList(List<T> list);
        /// <summary>
        /// 设置当前sheet页做多录入多少条数据
        /// </summary>
        /// <param name="pageLimt">每页多少条数据</param>
        /// <returns></returns>
        IFastNpoi<T> SetPageLimit(int pageLimt);
        /// <summary>
        /// 设置表头映射规则(此规则优先级高于实体上的特性)
        /// </summary>
        /// <param name="columnName">表头名</param>
        /// <param name="columnExpression">映射属性表达式</param>
        /// <param name="width">表格宽度</param>
        /// <param name="operationType">表头类型(导入,导出，导入和导出)</param>
        /// <param name="position">生成表头位置</param>
        /// <param name="mergeCell">是否合并单元格</param>
        /// <returns></returns>
        IFastNpoi<T> HeaderMapper(string columnName,Expression<Func<T,object>> columnExpression, int width=0,OperationType operationType= OperationType.Import_Export, int position=999,bool mergeCell=false);
        /// <summary>
        /// 设置表头映射规则(此规则优先级高于实体上的特性)
        /// </summary>
        /// <param name="columnName">表头名</param>
        /// <param name="propertyName">映射的属性名称</param>
        /// <param name="width">表格宽度</param>
        /// <param name="operationType">表头类型(导入,导出，导入和导出)</param>
        /// <param name="position">生成表头位置</param>
        /// <param name="mergeCell">是否合并单元格</param>
        /// <returns></returns>
        IFastNpoi<T> HeaderMapper(string columnName, string propertyName, int width = 0, OperationType operationType = OperationType.Import_Export, int position = 999,bool mergeCell=false);
        /// <summary>
        /// 数据操作
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        IFastNpoi<T> DataMapper(Action<T> action);
        /// <summary>
        /// 表格合并
        /// </summary>
        /// <param name="startRowIndex">起始行序数</param>
        /// <param name="endRowIndex">结束行序数</param>
        /// <param name="startColumnIndex">起始列序数</param>
        /// <param name="endColumnIndex">结束列序数</param>
        /// <param name="sheetIndex">应用于哪个sheet,默认-1为全体sheet</param>
        /// <returns></returns>
        IFastNpoi<T> MergeCell(int startRowIndex,int endRowIndex,int startColumnIndex,int endColumnIndex,int sheetIndex=-1);
        /// <summary>
        /// 使用CommentModel模型对指定cell添加批注
        /// </summary>
        /// <param name="commentModels"></param>
        /// <returns></returns>
        IFastNpoi<T> CommentCell(List<CommentModel> commentModels);
        IFastNpoi<T> CommentCell(Func<Dictionary<string, int>, List<CommentModel>> func);
        /// <summary>
        /// 对sheet进行追加操作
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        IFastNpoi<T> SheetMapper(Action<ISheet> action);
        /// <summary>
        /// 使特性中的position属性失效
        /// </summary>
        /// <returns></returns>
        IFastNpoi<T> DisableOrderby();
        /// <summary>
        /// 不生成header(一般用于模板写入，表头使用模板的)
        /// </summary>
        /// <returns></returns>
         IFastNpoi<T> DisableHeader();
        /// <summary>
        /// 将workbook转化成为xlsx文件
        /// </summary>
        /// <param name="dirPath">生成地址的文件夹路径</param>
        /// <returns>文件名称</returns>
         string ToFile(string dirPath);
        /// <summary>
        /// 将workbook转化为byte数组
        /// </summary>
        /// <returns></returns>
         byte[] ToByte();
        /// <summary>
        /// 将workbook的数据转化为实体list
        /// </summary>
        /// <returns></returns>
         List<T> ToList();

    }
}
